#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>

#define BUF_SIZE 30
void error_handling(char *message);

int main(int argc, char *argv[])
{
    WSADATA wsaData;
    SOCKET acpt_sock, recv_sock;
    SOCKADDR_IN recv_adr, serv_adr;
    int str_len, serv_adr_sz;
    char buf[BUF_SIZE];
    int result;

    fd_set read, except, readCopy, exceptCopy;
    struct timeval timeout;

    if (argc != 2)
    {
        printf("Usage : %s <port>\n", argv[0]);
        exit(1);
    }

    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
        error_handling("WSAStartup() error!");

    acpt_sock = socket(PF_INET, SOCK_STREAM, 0);
    memset(&recv_adr, 0, sizeof(recv_adr));
    recv_adr.sin_family = AF_INET;
    recv_adr.sin_addr.s_addr = htonl(INADDR_ANY);
    recv_adr.sin_port = htons(atoi(argv[1]));

    if (bind(acpt_sock, (SOCKADDR *)&recv_adr, sizeof(recv_adr)) == SOCKET_ERROR)
        error_handling("bind() error");
    if (listen(acpt_sock, 5) == SOCKET_ERROR)
        error_handling("listen() error");

    serv_adr_sz = sizeof(serv_adr);
    recv_sock = accept(acpt_sock, (SOCKADDR *)&serv_adr, &serv_adr_sz);

    FD_ZERO(&read);
    FD_ZERO(&except);
    FD_SET(recv_sock, &read);
    FD_SET(recv_sock, &except);

    while (1)
    {
        readCopy = read;
        exceptCopy = except;
        timeout.tv_sec = 5;
        timeout.tv_usec = 0;

        result = select(0, &readCopy, 0, &exceptCopy, &timeout);
        if (result > 0)
        {
            if (FD_ISSET(recv_sock, &exceptCopy))
            {
                str_len = recv(recv_sock, buf, BUF_SIZE - 1, MSG_OOB);
                buf[str_len] = 0;
                printf("Urgent message: %s \n", buf);
            }

            if (FD_ISSET(recv_sock, &readCopy))
            {
                str_len = recv(recv_sock, buf, BUF_SIZE - 1, 0);
                if (str_len == 0)
                {
                    break;
                    closesocket(recv_sock);
                }
                else
                {
                    buf[str_len] = 0;
                    puts(buf);
                }
            }
        }
    }

    closesocket(acpt_sock);
    WSACleanup();
    return 0;
}

void error_handling(char *message)
{
    fputs(message, stderr);
    fputc('\n', stderr);
    exit(1);
}